using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace Kugar.Core.ExtMethod
{
    public static class UriAbout
    {
        public static IPAddress GetHostIPAddress(this Uri srcUri)
        {
            if (srcUri == null)
            {
                return null;
            }
            else
            {
                var remoteUri = srcUri.Host;

                //if (srcUri.Port>0)
                //{
                //    remoteUri += (":" + srcUri.Port);
                //}

                var ip = Dns.GetHostAddresses(remoteUri);

                return ip == null || ip.Length <= 0 ? null : ip[0];
            }
        }

        public static Uri ToUri(this string srcUriStr)
        {
            return ToUri(srcUriStr, UriKind.RelativeOrAbsolute, null);
        }

        public static Uri ToUri(this string srcUriStr, Uri defaultValue)
        {
            return ToUri(srcUriStr, UriKind.RelativeOrAbsolute, defaultValue);
        }

        public static Uri ToUri(this string srcUriStr, UriKind uriKind)
        {
            return ToUri(srcUriStr, uriKind, null);
        }

        public static Uri ToUri(this string srcUriStr, UriKind uriKind, Uri defaultValue)
        {
            if (srcUriStr.IsNullOrEmpty())
            {
                return defaultValue;
            }

            Uri remoteUri;

            if (Uri.TryCreate(srcUriStr, uriKind, out remoteUri))
            {
                return remoteUri;
            }
            else
            {
                return defaultValue;
            }
        }

        public static Dictionary<string, string> GetQueryInfo(this Uri srcUri)
        {
            if (srcUri == null)
            {
                return null;
            }

            var tempDic = new Dictionary<string, string>(3, StringComparer.CurrentCultureIgnoreCase);

            if (srcUri.Query.IsNullOrEmpty())
            {
                return tempDic;
            }

            var queryString = srcUri.Query.TrimStart('?');

            var item = queryString.Split('&');

            foreach (var s in item)
            {
                var slist = s.Split('=');
                if (slist.Length == 2)
                {
                    if (slist[1].IsNullOrEmpty())
                    {
                        continue;
                    }

                    var v = Uri.EscapeUriString(slist[1]);

                    //var v = HttpHelper.Decode(slist[1], Encoding.UTF8);
                    if (tempDic.ContainsKey(slist[0]))
                    {
                        tempDic[slist[0]] = v;
                    }
                    else
                    {
                        tempDic.Add(slist[0], v);
                    }

                }
                else
                {
                    tempDic.Add(s, string.Empty);
                }
            }

            return tempDic;
        }

        private static long aBegin = (IPAddress.Parse("10.0.0.0")).Address;
        private static long aEnd = (IPAddress.Parse("10.255.255.255")).Address;
        private static long bBegin = (IPAddress.Parse("172.16.0.0")).Address;
        private static long bEnd = (IPAddress.Parse("172.31.255.255")).Address;
        private static long cBegin = (IPAddress.Parse("192.168.0.0")).Address;
        private static long cEnd = (IPAddress.Parse("192.168.255.255")).Address;

        public static bool IsLocalNetworkAddress(this string ipAddress)
        {
            IPAddress ipad;

            if (IPAddress.TryParse(ipAddress, out ipad))
            {
                return IsLocalNetworkAddress(ipad);
            }
            else
            {
                return false;
            }
        }

        public static bool IsLocalNetworkAddress(this IPAddress srcAddress)
        {
            var ad = srcAddress.Address;

            if (srcAddress == IPAddress.Loopback || ad.IsBetween(aBegin, aEnd) || ad.IsBetween(bBegin, bEnd) || ad.IsBetween(cBegin, cEnd))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

}